package cn.chinaflame.pagodas.service;

 

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.chinaflame.pagodas.constant.Constant;
import cn.chinaflame.pagodas.constant.Sysconst;
import cn.chinaflame.pagodas.entity.PaMember;
import cn.chinaflame.pagodas.entity.PaOrder;
import cn.chinaflame.pagodas.entity.PaOrderitem;
import cn.chinaflame.pagodas.entity.PaProduct;
import cn.chinaflame.pagodas.enums.CodeEnum;
import cn.chinaflame.pagodas.repository.PaMemberRepository;
import cn.chinaflame.pagodas.repository.PaOrderRepository;
import cn.chinaflame.pagodas.repository.PaOrderitemRepository;
import cn.chinaflame.pagodas.repository.PaProductRepository;
import cn.chinaflame.pagodas.req.PaHeadReq;
import cn.chinaflame.pagodas.utils.DateTimes;
import cn.chinaflame.pagodas.utils.MapHeadUtil;
import cn.chinaflame.pagodas.utils.ParamPreconditions;
import cn.chinaflame.pagodas.utils.stl.Base64Util;
import cn.chinaflame.pagodas.utils.stl.HttpClientUtils;
import cn.chinaflame.pagodas.utils.stl.JsonUtil;
import cn.chinaflame.pagodas.utils.stl.MD5Util;
import cn.chinaflame.pagodas.utils.stl.MapUtil;

/**
* @author    created by lbq
* @date	     2018年7月19日 下午3:46:19
**/
@Service
public class PayJsApiService {
	private static Logger log = LoggerFactory.getLogger(PayJsApiService.class);
	private static Map<String, String> param = new HashMap<String, String>();
	final static String signType = "2";
	@Autowired
	private PaOrderRepository paOrderRepository;
	@Autowired
	private PaProductRepository paProductRepository;
	@Autowired
	private PaOrderitemRepository paOrderitemRepository;
	@Autowired
	private PaMemberRepository paMemberRepository;
	@Autowired
	private PaOrderService paOrderService;
	@Value("${pay.payment.notify_ty_url}")
	private String payNoticeUrl;
	@Value("${pay.payment.return_ty_url}")
	private String payReturnUrl;
	
	/**
	 * 佛龛JsApi支付
	 * @throws Exception
	 */
	@Transactional
	public Object JsApi(PaHeadReq req) throws Exception{
		log.info("手机"+req.getMobile()+"orderId"+req.getOrderId());
		// 设置请求头
		Map<String, String> headMap= MapHeadUtil.headMap(req.getOrderId());
		//订单表
		PaOrder order=paOrderRepository.findPaOrderById(req.getOrderId());
		ParamPreconditions.checkNotNull(order, CodeEnum.FAIL.getCode(),"没有此订单");
		//订单详情
		PaOrderitem paOrderitem=paOrderitemRepository.findOrderItemById(order.getId());
		ParamPreconditions.checkNotNull(paOrderitem, CodeEnum.FAIL.getCode(),"没有此订单");
		//商品表
		PaProduct product=paProductRepository.findProdictById(paOrderitem.getProductId());
		ParamPreconditions.checkNotNull(product, CodeEnum.FAIL.getCode(),"没有该商品");
		//会员表
		PaMember member=paMemberRepository.findByMobile(req.getMobile());
		ParamPreconditions.checkNotNull(member, CodeEnum.FAIL.getCode(),"没有此会员");
		log.info("名字"+member.getNickName());
		
		ParamPreconditions.checkArgument(req.getMobile().equals(order.getMobile()), CodeEnum.FAIL.getCode(), "付款人手机号和下单人手机号不匹配");
		
		// 设置请求正文
		Map<String, String> contentMap = new LinkedHashMap<String, String>();
		contentMap.put("customerIP", req.getCustomerIP());
		contentMap.put("orderAmount", order.getMoney().multiply(new BigDecimal(100)).setScale(0, RoundingMode.UNNECESSARY)+"");
		contentMap.put("displayName", "fokan");
		contentMap.put("goodsName", product.getName());
		contentMap.put("goodsCount", paOrderitem.getNumber()+"");
		contentMap.put("payType", "js");//js 微信公众号  qrcode扫码 
		contentMap.put("orgCode", "wechatpay");//目标资金机构代码： 1.alipay支付宝  2.wechatpay微信 
		contentMap.put("directFlag", "1");
		contentMap.put("channelCode", "");
		contentMap.put("platformId", "");//商户所属平台商编号
		contentMap.put("returnUrl", payReturnUrl);//商户回调地址
		contentMap.put("noticeUrl", payNoticeUrl);//商户通知地址 后台
		contentMap.put("buyerId", member.getOpenid());//买家为支付宝（user_Id）买家为微信（open_id）
		contentMap.put("remark", "remark备注");
		//签名
		Map<String, Object> signMap = new LinkedHashMap<String, Object>();
		signMap.put("head", headMap);
		signMap.put("content", contentMap);

		String signStr = JsonUtil.toJSonString(signMap);
		System.out.println("signStr:" + signStr);
		String strMd5 = MD5Util.md5Hex(signStr);
		String sign =strMd5 +Constant.publicKey;
		System.out.println("待进行MD5源串:" + sign);
		sign = MD5Util.md5Hex(sign);
		System.out.println("查看签名"+sign);
		Map<String, Object> paraMap = new LinkedHashMap<String, Object>();
		paraMap.put("head", headMap);
		paraMap.put("content", contentMap);
		paraMap.put("sign", sign);
		String jsonStr = JsonUtil.toJSonString(paraMap);
		System.out.println("提交串：" + jsonStr);
		String msg = new String(Base64Util.encode(jsonStr.getBytes()));
		msg = URLEncoder.encode(msg, "utf-8");
		param.put("msg", msg);
		String params = MapUtil.map2string(param); 
		System.out.println("提交参数：" + params);
		String resultStr = HttpClientUtils.sendPost(Constant.REQ_URL, params);
		
		System.out.println("同步提交返回：" + resultStr);
		msg = resultStr.substring(4);
		Map content= parse(msg);
		String responseCode= (String) content.get("responseCode");
		if(responseCode.equals("0001")){
			order.setPayTime(DateTimes.nowDateTime());
			order.setUpdatetime(DateTimes.nowDateTime());
			order.setPayStatus(Sysconst.PAY_STATUS_DOING);
			order = paOrderRepository.saveAndFlush(order);
		}
		
		
		
		
		
		return (String) content.get("codeUrl");
	}
	/**
	 * 接收后台通知
	 * 
	 * @param request
	 * @return
	 */
	public String notifyBkgUrl(HttpServletRequest request) {
		System.out.println("************************* 接收到后台通知 *****************************");
		String msg = request.getParameter("msg");
		System.out.println("接收到通知能数：msg=" + msg);
		// 进行验签
		try {
			String msg1 = new String(Base64Util.decode(msg.getBytes()), "UTF-8");
			System.out.println("base64解签后：" + msg1);
			
			Map<String, Object> jsonMap = JsonUtil.jsonToMap(msg1);
			Map head = (Map) jsonMap.get("head");
			Map content = (Map) jsonMap.get("content");
			String sign = (String) jsonMap.get("sign");

			Map<String, Object> signMap = new HashMap();
			signMap.put("head", head);
			signMap.put("content", content);

			String signStr = JsonUtil.toJSonString(signMap);
			System.out.println("signStr:" + signStr);
			
			String strMd5 = MD5Util.md5Hex(signStr);
			
			String  signVal = strMd5 + Constant.publicKey;
			signVal = MD5Util.md5Hex(signVal);
			System.out.println("验签前的值：" + signVal);
			System.out.println("验签结果：" + sign.equalsIgnoreCase(signVal));
			ParamPreconditions.checkArgument(sign.equalsIgnoreCase(signVal), CodeEnum.FAIL.getCode(), "验签失败");
			paOrderService.orderUpdate(content.get("merOrderId").toString(), content.get("stateCode").toString());
		} catch (Exception e) {
			System.out.println("寻灯逻辑异常;" + e.getMessage());
			// 返回
			return String.valueOf("FAIL");
		}

		return String.valueOf("OK");
	}

	
	/**
	 * 6.10订单结算状态同步
	 * @param args
	 * @throws Exception
	 */
	public static String orderSybcSetment(String orderId) throws Exception{
			// 设置请求头
			Map<String, String> headMap = MapHeadUtil.headMapForOrderSybc();
			// 设置请求正文
			Map<String, String> contentMap = new LinkedHashMap<String, String>();
			contentMap.put("merOrderId", orderId);//商户订单号
			contentMap.put("settlementFlag", "1");// 0-不可结算，1-可结算
			//验签
			Map<String, Object> signMap = new LinkedHashMap<String, Object>();
			signMap.put("head", headMap);
			signMap.put("content", contentMap);
			String signStr = JsonUtil.toJSonString(signMap);
			System.out.println("signStr:" + signStr);
			String strMd5 = MD5Util.md5Hex(signStr);//验签JSON做MD5加密
			System.out.println("加密结果：" + strMd5);
			//MD5
			String signValue = strMd5 + Constant.publicKey;
			System.out.println("待进行MD5源串:" + signValue);
			signValue = MD5Util.md5Hex(signValue);
			/**
			 * 拼入参map
			 */
			Map<String, Object> paraMap = new LinkedHashMap<String, Object>();
			paraMap.put("head", headMap);
			paraMap.put("content", contentMap);
			paraMap.put("sign", signValue);
			String jsonStr = JsonUtil.toJSonString(paraMap);
			System.out.println("提交串：" + jsonStr);
			/**
			 * 将入参json转为Base64进行http传输
			 */
			String msg = new String(Base64Util.encode(jsonStr.getBytes()));
			msg = URLEncoder.encode(msg, "utf-8");
			param.put("msg", msg);
			String resultStr = HttpClientUtils.sendPost(Constant.REQ_URL, MapUtil.map2string(param));
			System.out.println("同步提交返回：" + resultStr);
			return null;
	}
	
	
	
	
	
	
	
	
	
	//签名校验
	public static Map parse(String msg) throws Exception {
		String msg1 = new String(Base64Util.decode(msg.getBytes()), "UTF-8");
		 System.out.println("base64解签后：" + msg1);
		Map<String, Object> jsonMap = JsonUtil.jsonToMap(msg1.toString());
		Map head = (Map) jsonMap.get("head");
		Map content = (Map) jsonMap.get("content");
		String sign = (String) jsonMap.get("sign");

		Map<String, Object> signMap = new HashMap();
		signMap.put("head", head);
		signMap.put("content", content);

		String signStr = JsonUtil.toJSonString(signMap);
		System.out.println("呵呵呵signStr:" + signStr);
		String strMd5 = MD5Util.md5Hex(signStr);
		System.out.println("加密结果：" + strMd5);
		
		String signValue = strMd5 + Constant.publicKey;
		System.out.println("待进行MD5源串:" + signValue);
		signValue = MD5Util.md5Hex(signValue);
		
		System.out.println("解密结果：" + signValue);

		//return (String) content.get("codeUrl");
		return content;
	}
	
	
}
